package acwing_01;
import java.io.*;
import java.util.*;
public class _798_差分_差分矩阵_ilike_详细注释 {
	static int N = 1010;
	static int n,m,q;
	static int arr[][] = new int[N][N];
	static int d[][] = new int[N][N];
	static int x1,y1,x2,y2,c;
	/*
	 * 我自己更喜欢的思路：
	 * 1. arr数组存输入的值
	 * 2. d数组存操作后的差分值
	 * 3. d数组取前缀和
	 * 4. 遍历arr[i][j] + d[i][i] = 最终结果！
	 * 
	 * 一维数组前缀和是   d的当前值加前面一个数的值
	 * 一维数组差分是     d的当前值 减前一个arr值 加当前arr值
	 * 二维数组的前缀和是 d的当前值 加左边格子的值 加上面格子的值 减左上角格子的值
	 * 二维数组的差分是   d矩阵的左上角第一格+c 矩阵左下角下一格-c 矩阵右上角右一格-c 矩阵右下角右下格+c
	 * */
	public static void main(String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		
		StringTokenizer st = new StringTokenizer(br.readLine());
		
		n = Integer.parseInt(st.nextToken());
		m = Integer.parseInt(st.nextToken());
		q = Integer.parseInt(st.nextToken());
		
		for(int i = 1; i <= n; i++) {
			st = new StringTokenizer(br.readLine());
			for(int j = 1; j <= m; j++) {
				arr[i][j] = Integer.parseInt(st.nextToken());
			}
		}
		
		
		for(int i = 0; i < q; i++) {
			st = new StringTokenizer(br.readLine());
			x1 = Integer.parseInt(st.nextToken());
			y1 = Integer.parseInt(st.nextToken());
			x2 = Integer.parseInt(st.nextToken());
			y2 = Integer.parseInt(st.nextToken());
			c = Integer.parseInt(st.nextToken());
			// x1行y1列格子+c，那么x1y1之后的行列进行前缀和计算时，都会加上c
			d[x1][y1] += c;
			// 把矩阵的左下角下一格开始的元素都-c，这部分是不需要c的，但是因为上一步操作导致后续前缀和计算会加上c
			d[x2 + 1][y1] -= c;
			// 把矩阵右上角右一格开始的元素都-c
			d[x1][y2 + 1] -= c;
			// 上面两步进行了-c，导致有一部分值重复-c，这里需要把右下角右下格+c，把多删的c补回来
			d[x2 + 1][y2 + 1] += c;
		}
		
		for(int i = 1; i <= n; i++) {
			for(int j = 1; j <= m; j++) {
				// 二维数组的前缀和是 当前值 加左边格子的值 加上面格子的值 减左上角格子的值
				d[i][j] = d[i][j] + d[i - 1][j] + d[i][j - 1] - d[i - 1][j - 1];
				arr[i][j] += d[i][j];
				bw.write(arr[i][j] + " ");
			}
			bw.newLine();
		}
		
		bw.flush();
		br.close();
		bw.close();
	}
	
}
